/**
 * 我们要编写这样的AST, 还原代码
 *
 * 先把代码copy到 https://astexplorer.net/ 网站上，查看生成的AST结构，然后逐层创建
 */
/**
 import React from 'react'
import {Button} from 'antd'

export default (props) => {
  const handleClick = (ev) => {
    console.log(ev);
  }

  return <Button onClick={handleClick}>{props.name}</Button>
}
 */

// 运行环境： node: 20.10.0
// npx ts-node .\src\04-react-jsx.ts
// 在js版本里面 可以直接 import types from '@babel/types', 在 ts写法里面不行，从@babel/types类型声明文件中，都是 export {} 这种导出的，所以要稍微调整一下
import * as types from '@babel/types'

// js里面 esm 格式  import * as x from '@babel/generator', 使用  x.default(xxx).code
// 在ts 里面， 直接如下导入
import generate from '@babel/generator'

let p1 = types.program(
	// 第一个import
	[
		types.importDeclaration(
			[types.importDefaultSpecifier(types.identifier('React'))],
			// 第二个参数，导入的来源, 指定 import xxx from 'react'， 指定表达式中的'react' 这一块
			types.stringLiteral('react')
		),

		// 第二个import
		// import {Button} from 'antd'
		types.importDeclaration(
			[
				types.importSpecifier(
					types.identifier('Button'),
					types.identifier('Button')
				),
			],
			types.stringLiteral('antd')
		),

    // 创建默认导出 export default (props) => {}
		types.exportDefaultDeclaration(
			// 箭头函数
			types.arrowFunctionExpression(
				// 函数参数
				[types.identifier('props')],

				// 默认导出的 函数体
				types.blockStatement([
					types.variableDeclaration('const', [
						types.variableDeclarator(
							types.identifier('handleClick'),

							types.arrowFunctionExpression(
								[types.identifier('ev')],
								// handleClick的函数体
								types.blockStatement([
									types.expressionStatement(
										types.callExpression(types.identifier('conosle.log'), [
											types.identifier('ev'),
										])
									),

                  // 返回语句  return 1
                  types.returnStatement(
                    types.numericLiteral(1)
                  )
								])
							)
						),
					]),

          // jsx代码片段, jsx 语法里面需要返回 内容

          types.returnStatement(
            types.jsxElement(
              types.jsxOpeningElement(
                types.jsxIdentifier('Button'),
                [
                  // 属性, onClick={handleClick}
                  types.jsxAttribute(
                    types.jsxIdentifier('onClick'),
                    types.jsxExpressionContainer(types.identifier('handleClick'))
                  )
                ]
              ),
              types.jsxClosingElement(
                types.jsxIdentifier('Button')
              ),
              // 子元素
              [
                types.jsxExpressionContainer(
                  types.identifier('props.name')
                )
              ]
            )
          )
				])
			)
		),
	]
)

console.log(generate(p1).code)
